Isolating the $scope From the Directive

Course- AngularJS >

In the example above the userinfo directive was bound hard to the $scope variable because the HTML template referenced the textToInsert property directly. Referencing $scope variables directly makes it hard to reuse the directive more than once within the same controller, since the $scope variables typically have the same values everywhere inside the same controller. For instance, if you wanted to have this HTML in your page:

<userinfo></userinfo>
<userinfo></userinfo>

Then the two <userinfo> elements would be replaced by the same HTML template, which is bound to the same $scope variable. The result would be that the two <userinfo> elements would be replaced by the exact same HTML code.

To be able to bind the two <userinfo> elements to different values in the $scope object, you need to bind the HTML template to an isolate scope.

An isolate scope is a separate scope object tied to the directive. Here is how you define it in the directive definition object:

myapp.directive('userinfo', function() {
    var directive = {};

    directive.restrict = 'E';

    directive.template = "User : {{user.firstName}} {{user.lastName}}";

    directive.scope = {
        user : "=user"
    }

    return directive;
})

Notice how the HTML template has two interpolation directives bound to {{user.firstName}} and {{user.lastName}}. Notice the user. part. And notice the directive.scope property. The directive.scope property is a JavaScript object which contains a property named user. The directive.scope property is the isolate scope object, and the HTML template is now bound to the directive.scope.user object (via the {{user.firstName}} and {{user.lastName}} interpolation directives).

The directive.scope.user property is set to "=user". That means, that the directive.scope.user property is bound to the property in the scope property (not in the isolate scope) with the name passed to the user attribute of the <userinfo> element. It sounds confusing, so look at this HTML example:

<userinfo user="jakob"></userinfo>
<userinfo user="john"></userinfo>

These two <userinfo> element contain a user attribute. The value of these attributes contain the names of properties in the $scope object which are to be referenced by the isolate scope object's userinfo property.

Here is a full example:

<userinfo user="jakob"></userinfo>
<userinfo user="john"></userinfo>

<script>
myapp.directive('userinfo', function() {
    var directive = {};

    directive.restrict = 'E';

    directive.template = "User : <b>{{user.firstName}}</b> <b>{{user.lastName}}</b>";

    directive.scope = {
        user : "=user"
    }

    return directive;
});

myapp.controller("MyController", function($scope, $http) {
    $scope.jakob = {};
    $scope.jakob.firstName = "Jakob";
    $scope.jakob.lastName  = "aitechtonic";

    $scope.john = {};
    $scope.john.firstName = "John";
    $scope.john.lastName  = "Doe";
});

</script>